package edu.gmu.messages;

import edu.gmu.middleware.Message;
import edu.gmu.streams.BlockInputStream;
import edu.gmu.streams.BlockOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class Neighbors implements Message
{
    public EndPoint neighbor;
    
    public List<EndPoint> next;
    public List<EndPoint> prev;

    public Neighbors()
    {

    }
    
    public Neighbors(   EndPoint neighbor,
                        List<EndPoint> next,
                        List<EndPoint> prev  )
    {
        this.neighbor = neighbor;
        this.next = next;
        this.prev = prev;
    }
    
    public void setNeighbor( EndPoint neighbor )
    {
        this.neighbor = neighbor;
    }

    public EndPoint getNeighbor()
    {
        return this.neighbor;
    }

    public void setNext( List<EndPoint> next )
    {
        this.next = next;
    }

    public List<EndPoint> getNext()
    {
        return this.next;
    }
    
    public void setPrev( List<EndPoint> prev )
    {
        this.prev = prev;
    }

    public List<EndPoint> getPrev()
    {
        return this.prev;
    }


    public void marshal(BlockOutputStream stream) throws IOException
    {
        this.neighbor.marshal(stream);
        
        stream.writeInt( this.next.size() );
        for (int i = 0; i < next.size(); i++)
        {
            EndPoint endPoint = next.get(i);
            endPoint.marshal(stream);
        }
        
        stream.writeInt( this.prev.size() );
        for (int i = 0; i < prev.size(); i++)
        {
            EndPoint endPoint = prev.get(i);
            endPoint.marshal(stream);
        }
    }

    public void unmarshal(BlockInputStream stream) throws IOException
    {
        this.neighbor = new EndPoint();
        this.neighbor.unmarshal(stream);
        
        int nextSize = stream.readInt();
        this.next = new ArrayList<EndPoint>();
        for (int i = 0; i < nextSize; i++)
        {
            EndPoint nextNeighbor = new EndPoint();
            nextNeighbor.unmarshal(stream);
            this.next.add(nextNeighbor);
        }
        
        int prevSize = stream.readInt();
        this.prev = new ArrayList<EndPoint>();
        for (int i = 0; i < prevSize; i++)
        {
            EndPoint prevNeighbor = new EndPoint();
            prevNeighbor.unmarshal(stream);
            this.prev.add(prevNeighbor);
        }
    }
    
    public String toString()
    {
        StringBuffer buf = new StringBuffer();
        buf.append( "Neighbor: "+this.neighbor.toString() );
        for (int i = 0; i < next.size(); i++)
        {
            EndPoint endPoint = next.get(i);
            buf.append( "\n    next "+i+ ": "+endPoint );
        }
        for (int i = 0; i < prev.size(); i++)
        {
            EndPoint endPoint = prev.get(i);
            buf.append( "\n    prev "+i+ ": "+endPoint );
        }
        return buf.toString() +"\n";
    }
}
